package com.library.management.repository;

import com.library.management.entity.BookCategory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

/**
 * 图书分类数据访问层接口
 * 提供图书分类相关的数据库操作
 *
 * @author 开发者
 * @version 1.0
 * @since 2025-10-20
 */
@Repository
public interface BookCategoryRepository extends JpaRepository<BookCategory, Long> {

    // ========== 基础查询方法 ==========

    /**
     * 根据分类编码查找分类
     *
     * @param categoryCode 分类编码
     * @return 分类对象
     */
    Optional<BookCategory> findByCategoryCode(String categoryCode);

    /**
     * 根据分类名称查找分类
     *
     * @param categoryName 分类名称
     * @return 分类对象
     */
    Optional<BookCategory> findByCategoryName(String categoryName);

    /**
     * 检查分类编码是否存在
     *
     * @param categoryCode 分类编码
     * @return true-存在，false-不存在
     */
    boolean existsByCategoryCode(String categoryCode);

    // ========== 树形结构查询 ==========

    /**
     * 查找所有根分类（没有父分类的分类）
     *
     * @return 根分类列表
     */
    List<BookCategory> findByParentIsNull();

    /**
     * 根据父分类查找子分类
     *
     * @param parent 父分类
     * @return 子分类列表
     */
    List<BookCategory> findByParent(BookCategory parent);

    /**
     * 根据父分类ID查找子分类
     *
     * @param parentId 父分类ID
     * @return 子分类列表
     */
    List<BookCategory> findByParentId(Long parentId);

    /**
     * 查找叶子分类（没有子分类的分类）
     */
    @Query("SELECT c FROM BookCategory c WHERE c.children IS EMPTY")
    List<BookCategory> findLeafCategories();

    // ========== 排序相关查询 ==========

    /**
     * 查找所有根分类并按排序字段排序
     *
     * @return 排序后的根分类列表
     */
    List<BookCategory> findByParentIsNullOrderBySortOrderAsc();

    /**
     * 根据父分类查找子分类并按排序字段排序
     *
     * @param parent 父分类
     * @return 排序后的子分类列表
     */
    List<BookCategory> findByParentOrderBySortOrderAsc(BookCategory parent);

    /**
     * 根据排序字段范围查询分类
     *
     * @param minOrder 最小排序值
     * @param maxOrder 最大排序值
     * @return 分类列表
     */
    List<BookCategory> findBySortOrderBetween(Integer minOrder, Integer maxOrder);

    // ========== 复杂查询方法 ==========

    /**
     * 查找分类名称包含指定关键词的分类
     *
     * @param keyword 关键词
     * @return 分类列表
     */
    List<BookCategory> findByCategoryNameContainingIgnoreCase(String keyword);

    /**
     * 统计每个分类下的图书数量
     */
    @Query("SELECT c, COUNT(b) FROM BookCategory c LEFT JOIN c.books b GROUP BY c")
    List<Object[]> countBooksInEachCategory();

    /**
     * 查找指定深度的分类
     *
     * @param depth 深度（从1开始）
     * @return 分类列表
     */
    @Query(value = "WITH RECURSIVE category_tree AS (" +
            "  SELECT id, category_name, parent_id, 1 as depth " +
            "  FROM book_categories WHERE parent_id IS NULL " +
            "  UNION ALL " +
            "  SELECT c.id, c.category_name, c.parent_id, ct.depth + 1 " +
            "  FROM book_categories c " +
            "  INNER JOIN category_tree ct ON c.parent_id = ct.id" +
            ") SELECT * FROM category_tree WHERE depth = :depth",
            nativeQuery = true)
    List<Object[]> findCategoriesByDepth(@Param("depth") int depth);

    /**
     * 查找分类的完整路径
     *
     * @param categoryId 分类ID
     * @return 路径信息
     */
    @Query(value = "WITH RECURSIVE category_path AS (" +
            "  SELECT id, category_name, parent_id, category_name as path " +
            "  FROM book_categories WHERE id = :categoryId " +
            "  UNION ALL " +
            "  SELECT c.id, c.category_name, c.parent_id, CONCAT(cp.path, ' > ', c.category_name) " +
            "  FROM book_categories c " +
            "  INNER JOIN category_path cp ON c.id = cp.parent_id" +
            ") SELECT * FROM category_path ORDER BY id",
            nativeQuery = true)
    List<Object[]> findCategoryPath(@Param("categoryId") Long categoryId);
}